
# encoding: utf-8
"""
@author: cxk
@contact: 1061736944@qq.com
@version: 1.1
@file: main.py
@time: 2021/4/22 0019 22:39
排列组合
"""
import tkinter as tk
from tkinter import messagebox
import xlrd,re
from itertools import combinations,permutations
import itertools,os,threading
from tkinter import *
from tkinter import filedialog
from tkinter.simpledialog import askinteger, askfloat, askstring
import tkinter.messagebox #这个是消息框，对话框的关键


class MainBox:
    def __init__(self):
        self.AppName = "排列组合"
        self.size = '1000x600'
        self.start_flg=False

    def chiose_xlsx(self):
        global file_path,X,Y
        X = askinteger(title = "请输入一个整数",prompt = "整型变量X：")
        file_path = filedialog.askopenfilename(title=u'选择文件', initialdir=(os.getcwd()))
        Y = askinteger(title = "请输入一个整数",prompt = "整型变量Y：")

    def result(self,all_list,X):	
        N=len(all_list)
        M=len(all_list[0])
        all_result=list(itertools.combinations(all_list, X))
        temp={}
        for i in range(len(all_result)):
            result = result =  set.intersection(*[set(list) for list in list(all_result[i])])
            temp['组合'+str(i+1)]=[result,len(result)]
        return all_result,temp

    def read_xlsx(self,xlsx_path):
        xlsfile = xlsx_path# 打开指定路径中的xlsx文件
        book = xlrd.open_workbook(xlsfile)#得到Excel文件的book对象，实例化对象
        sheet0 = book.sheet_by_index(0) # 通过sheet索引获得sheet对象
        nrows = sheet0.nrows# 获取行总数
        # ncols = sheet0.ncols#获取列总数
        all_list=[]
        for i in range(nrows):
            all_list.append([int(i) for i in sheet0.row_values(i)])
        return all_list
    
    def window_begin(self):
        global u
        begin = tk.Tk()
        begin.title(self.AppName)
        begin.geometry(self.size)

        def start():
            # 创建新线程
            thread1=threading.Thread(target=show)
            # 开启线程
            thread1.start()
            tkinter.messagebox.showinfo('提示','已开始计算，请等待！')
            self.start_flg=True

        def seach(ev=None):
            global result_all,Y,txt,all_len
            if self.start_flg:
                key_str = u.get()
                k=0
                text_list.delete(1.0,END)
                strs=key_str
                txts=""
                if strs!="":
                    txts="筛选情况以下：\n"
                    try:
                        results = list(map(int, re.split("[,，]",strs)))
                    except:
                        tkinter.messagebox.showerror('错误','筛选格式为例子：\n不输入：""\n一个数字："1"\n多个数字："1,2"')
                    for i in result_all:
                        no_exist = [False for a in results if a not in i]
                        if not no_exist:
                            txts+=str(i).replace('[',"").replace("]","")+"\n"
                            k+=1
                    L3['text']="筛选 "+strs+" 的共同项大于"+str(Y)+"的个数总数量："+str(k)
                    text_list.insert('insert',txts+"\n")
                else:
                    L3['text']="共同项大于"+str(Y)+"的个数总数量："+str(all_len)
                    text_list.insert('insert',txt+"\n")
            else:
                tkinter.messagebox.showerror('错误','请先进行计算！')  
                
        
        def delet(ev=None):
            global result_all,Y,txt,all_len
            if self.start_flg:
                key_str = c.get()
                k=0
                text_list.delete(1.0,END)
                strs=key_str
                txts=""
                if strs!="":
                    txts="忽略情况以下：\n"
                    try:
                        results = list(map(int, re.split("[,，]",strs)))
                    except:
                        tkinter.messagebox.showerror('错误','忽略格式为例子：\n不输入：""\n一个数字："1"\n多个数字："1,2"')
                    for i in result_all:
                        no_exist = [False for a in results if a not in i]
                        if not no_exist:
                            pass
                        else:
                            txts+=str(i).replace('[',"").replace("]","")+"\n"
                            k+=1
                    L3['text']="忽略后 "+strs+" 的共同项大于"+str(Y)+"的个数总数量："+str(k)
                    text_list.insert('insert',txts+"\n")
                else:
                    L3['text']="共同项大于"+str(Y)+"的个数总数量："+str(all_len)
                    text_list.insert('insert',txt+"\n")
            else:
                tkinter.messagebox.showerror('错误','请先进行计算！')  
            
        
        def show():
            global file_path,X,Y,result_all,txt,all_len
            result_all=[]
            text_list.delete(1.0,END)
            number,temp=self.result(self.read_xlsx(file_path),X)
            L['text']="排列组合总数量："+str(len(number))
            txt="共同项的个数≥3的共同项的情况有以下：\n"
            all_ll=[]
            for i in temp:
                if temp[i][1]>=Y  and temp[i][0] not in all_ll:
                    all_ll.append(temp[i][0])
                    none=list(temp[i][0])
                    none.sort()
                    result_all.append(none)
                    
            result_all.sort(key=lambda x: x[0], reverse=False)
            k=0
            for i in result_all:
                    txt+=str(i).replace('[',"").replace("]","")+"\n"
                    k+=1
            L3['text']="共同项大于"+str(Y)+"的个数总数量："+str(k)
            all_len=k
            text_list.insert('insert',txt+"\n")
            tkinter.messagebox.showinfo('提示','计算完成！')

    

        L = tk.Label(begin, text="结果筛选(回车键)：")
        L.place(relx=0.025,y=40)

        u = StringVar()
        key_input = tk.Entry(begin, textvariable=u,font=('微软雅黑', 16))
        key_input.place(relx=0.185, y=30, height=40, relwidth=0.10)
        
        L = tk.Label(begin, text="结果忽略(空格键)：")
        L.place(relx=0.285,y=40)
        
        c = StringVar()
        key_input2 = tk.Entry(begin, textvariable=c,font=('微软雅黑', 16))
        key_input2.place(relx=0.435, y=30, height=40, relwidth=0.10)
 
        button = tk.Button(begin, text='选择xlsx文件', command=self.chiose_xlsx)
        button.place(relx=0.55, y=6, height=40, relwidth=0.10)

        button2 = tk.Button(begin, text='开始计算', command=start)
        button2.place(relx=0.55, y=62, height=40, relwidth=0.10)
 
        L = tk.Label(begin, text="排列组合总数量：0")
        L.place(relx=0.68, y=10, height=40, relwidth=0.30)

        L3 = tk.Label(begin, text="共同项大于-的个数总数量：0")
        L3.place(relx=0.68, y=60, height=40, relwidth=0.30)
 
        key_input.bind("<Return>",seach)
        key_input2.bind("<space>",delet)
 
        # 创建滚动条
        scroll = Scrollbar(begin)
        text_list = tk.Text(begin, font=('微软雅黑', 11))
        text_list.place(relx=0.025, rely=0.2, relheight=0.75, relwidth=0.95)
        # 将滚动条填充
        scroll.pack(side=RIGHT,fill=Y) # side是滚动条放置的位置，上下左右。fill是将滚动条沿着y轴填充
        # 将滚动条与文本框关联
        scroll.config(command=text_list.yview) # 将文本框关联到滚动条上，滚动条滑动，文本框跟随滑动
        text_list.config(yscrollcommand=scroll.set) # 将滚动条关联到文本框
        # 返回
        def callback():
            if messagebox.askokcancel("退出", "是否退出{}？".format(self.AppName)):
                begin.destroy()
        begin.protocol("WM_DELETE_WINDOW", callback)
        begin.mainloop()
 
if __name__=="__main__":
    window = MainBox()
    window.window_begin()